<?php
namespace core\helper;
/**
 * 验证工具类
 */
class Verify{
    
    private static $errList = []; //
    
    /**
     * 验证规则是否符合
     */
    public static function check($data,$regType){
        $regRule = self::regList($regType);
        if( !$regRule )  logicE($regType.'校验规则不存在');
        return !!preg_match($regRule['reg'], trim( $data ));
    }
    
    /**
     * 批量验证规则是否符合
     * @param $regList 字段校验规则
     *  [[  
     *      'check' =>'must',            // 是否必填
            'msg'   =>'代理商ID不能为空',    // 检测失败的 提示信息
            'reg'   =>'int'        // 检测规则 int (必须数字); account/mobile/tel 已定义的正则 ; [ 1,2,3] 自定义范围
                      gt:0 // lt:100 bt:1:10 、 must 内容不能为空
            'val'   =>SYS_TIME, // 返回自定义值
            'def'   => 1 ,  // 默认值
        ]]
     * @param $data 需要校验的数据
     * @param $reportType 校验错误时处理方式 ： dataE 返回数据层异常, paramE 返回参数校验异常 , list 返回全部校验结果
     */
    public static function checks(array $regList,array $data,$reportType='dataE',$filter = true){
        $result = [];
        foreach( $regList as $key => $val ){
            // 没有传值 并且没有默认值 并且不是必传时 不赋值
            if( !isset($data[$key])){
                if(!$val) continue;
                if( is_array($val) ){
                    if( !isset($val['def']) && !isset($val['val'])  && $val['check'] != 'must'){
                        continue;
                    }
                }
            }
            
            // 没有校验规则时 直接赋值
            if( !$val ){
                isset($data[$key]) && $result[$key] = $data[$key]?:'';
                continue;
            }            
            // 规则强制设置某个字段的值
            if( isset($val['val']) ){
                $result[$key] = $val['val'];
                continue;
            }            
            // 存在默认值且外部没有值时可直接赋值
            if(( !isset($data[$key]) || !$data[$key] ) && (is_array($val['def']) && $val['def'])  ){
                $result[$key] = $val['def']; 
                continue;
            }
            // 该字段必须存在且不能为空
            if( isset($val['check']) && $val['check'] == 'must'){
                if( !isset($data[$key]) )  {
                    if( !$val['msg'] ) $val['msg'] = $key.'参数必填,不能为空';
                    self::reportErr($val['msg'],$reportType);
                    continue;
                }
            }
            // 规则校验
            if( isset($val['reg']) && $val['reg'] && isset($data[$key]) ){                
                if( is_array( $val['reg'] ) ){
                    if( !in_array($data[$key],$val['reg']) ){
                        if( !$val['msg'] ) $val['msg'] = $key.'参数超出预定范围';
                        self::reportErr($val['msg'],$reportType);
                        continue;
                    }
                }elseif( strtolower($val['reg']) == 'must' ) {
                    if(  $data[$key] === '' || is_null($data[$key]) ){
                        if( !$val['msg'] ) $val['msg'] = $key.'参数不能填空';
                        self::reportErr($val['msg'],$reportType);
                        continue;
                    }
                }elseif( strtolower($val['reg']) == 'int' ) {
                    if( !is_numeric($data[$key]) ){
                        if( !$val['msg'] ) $val['msg'] = $key.'参数必须为数值类型';
                        self::reportErr($val['msg'],$reportType);
                        continue;
                    }           
                }elseif( $reg = self::regList($val['reg']) ){
                    if( ! $data[$key] ) continue;
                    if(! preg_match($reg['reg'], trim( $data[$key] ))){
                        self::reportErr($reg['msg'],$reportType);
                        continue;
                    }
                }else{
                    $regArr = explode(':',$val['reg']);
					if(! in_array($regArr[0],['gt','lt','bt'] ) )  E('校验规则不存在');
					if(!$regArr[1])    E('校验规则不存在');
					
					if( $regArr[0] == 'gt'){
						if(!is_numeric($regArr[1]) )    E('校验规则错误');
						if($data[$key] < $regArr[1]){
							if( !$val['msg'] ) $val['msg'] = $key.'参数必须大于'.$regArr[1];
							self::reportErr($val['msg'],$reportType);
							continue;
						}
					}
					if( $regArr[0] == 'lt'){
						if(!is_numeric($regArr[1]) )    E('校验规则错误'.$val['reg']);
						if($data[$key] > $regArr[1]){
							if( !$val['msg'] ) $val['msg'] = $key.'参数必须小于'.$regArr[1];
							self::reportErr($val['msg'],$reportType);
							continue;
						}
					}
					if( $regArr[0] == 'bt'){
					    $error = false; $showl = ''; $showr = '';
					    $fristStr = substr($regArr[1],0,1);
                        $lsetStr  = substr($regArr[1],-1);
                        if(!in_array( $fristStr,['(','[']) || !in_array($lsetStr,[')',']'])) E('校验规则错误'.$val['reg']);
                                                 
                        if( $fristStr == '(') $regArr[1] = ltrim($regArr[1],'(');
                        if( $fristStr == '['){
                             $showl  = '等于';
                             $regArr[1] = ltrim($regArr[1],'[');
                        }
                        if( $lsetStr == ')') $regArr[1] = rtrim($regArr[1],')');
                        if( $lsetStr == ']'){
                            $showr  = '等于';
                            $regArr[1] = rtrim($regArr[1],']');
                        }
						$varList  = explode(',',$regArr[1]);
						if(!is_numeric($varList[0]) || !is_numeric($varList[1]) ) E('校验规则错误'.$val['reg']);
                        
                        if( $fristStr == '(' && $data[$key] <= $varList[0] ) $error = true;
                        if( $fristStr == '[' && $data[$key] <  $varList[0] ) $error = true;
                        if( $lsetStr == ')' && $data[$key] >= $varList[1] ) $error = true;
                        if( $lsetStr == ']' && $data[$key] >  $varList[1] ) $error = true;
                        if( $error ){
                            if( !$val['msg'] ) $val['msg'] = $key.'参数必须大于'.$showl.$varList[0].'并且小于'.$showr.$varList[1];
							self::reportErr($val['msg'],$reportType);
							continue;
                        }			
					}
                }
            }
            
            $result[$key] = trim($data[$key]);
        }
        return $result;
    }
    
    
    private static function reportErr($msg,$reportType){
        if( strtolower($reportType) == 'datae')  dataE( $msg );
        if( strtolower($reportType) == 'parame') paramE( $msg );
        self::$errList[] = $msg;        
    }
    
    /**
     * 规则列表
     */
    private static function regList($regType){
        $regList = array(
            'account' => ['reg'=> '/^[a-zA-Z][a-zA-Z0-9_]*$/' ,'msg' => '账号只能字母和数字组成'],
            'mobile'  => ['reg'=> '/^0?1[3-8][0-9]{9}$/', 'msg'=> '手机号码格式错误'],
            'email'   => ['reg'=> '/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/','msg'=> '邮箱格式错误'],
        );
        return $regList[$regType]?:'';
    }
    
}